package cn.signalpha.modules.shop.service;

import cn.signalpha.core.tool.utils.*;
import cn.signalpha.modules.com.dto.WalletDTO;
import cn.signalpha.modules.com.entity.enums.WalletSourceEnum;
import cn.signalpha.modules.com.entity.enums.WalletTypeEnum;
import cn.signalpha.modules.pay.dto.SettleOrderDTO;
import cn.signalpha.modules.pay.dto.SettleUserDTO;
import cn.signalpha.modules.pay.provider.IPayGranter;
import cn.signalpha.modules.pay.provider.PayGranterBuilder;
import cn.signalpha.modules.pay.vo.SettleOrderVO;
import cn.signalpha.modules.pay.vo.SettleUserVO;
import cn.signalpha.modules.shop.entity.OrderSettle;
import cn.signalpha.modules.shop.entity.enums.OrderSettleWayEnum;
import cn.signalpha.modules.shop.excel.OrderSettleExcel;
import cn.signalpha.modules.shop.mapper.OrderSettleMapper;
import cn.signalpha.modules.shop.vo.OrderSettleVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * 订单结算 服务类
 *
 * @author suguangjun
 */
@Service
@AllArgsConstructor
public class OrderSettleService extends ServiceImpl<OrderSettleMapper, OrderSettle> {

	private final SellerService sellerService;

	/**
	 * 自定义分页
	 */
    public IPage<OrderSettleVO> selectOrderSettlePage(IPage<OrderSettleVO> page, Map<String, Object> params) {
        return page.setRecords(baseMapper.selectOrderSettlePage(page, params));
    }

	/**
	 * 自定义统计
	 */
	public Double selectOrderSettleTotal(Map<String, Object> params) {
		return baseMapper.selectOrderSettleTotal(params);
	}

	/**
	 * 自定义分页
	 */
	public List<OrderSettleExcel> selectOrderSettleExcel(Map<String, Object> params) {
		return BeanUtil.copy(baseMapper.selectOrderSettlePage(null, params), OrderSettleExcel.class);
	}

	/**
	 * 自定义Wrapper
	 */
	public QueryWrapper<OrderSettle> selectOrderSettleWrapper(Map<String, Object> params) {
		QueryWrapper<OrderSettle> wrapper = Wrappers.query();
		wrapper.lambda().in(ObjectUtil.isNotEmpty(params.get("ids")), OrderSettle::getId, Func.toLongList(String.valueOf(params.get("ids"))));
		wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("userId")), OrderSettle::getUserId, params.get("userId"));
		wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("sellerId")), OrderSettle::getSellerId, params.get("sellerId"));
		wrapper.lambda().like(ObjectUtil.isNotEmpty(params.get("orderNo")), OrderSettle::getOrderNo, params.get("orderNo"));
		wrapper.lambda().like(ObjectUtil.isNotEmpty(params.get("payNo")), OrderSettle::getPayNo, params.get("payNo"));
		wrapper.lambda().like(ObjectUtil.isNotEmpty(params.get("payBizNo")), OrderSettle::getPayBizNo, params.get("payBizNo"));
		wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("payStatus")), OrderSettle::getPayStatus, params.get("payStatus"));
		wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("settleStatus")), OrderSettle::getSettleStatus, params.get("settleStatus"));
		wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("settleWay")), OrderSettle::getSettleWay, params.get("settleWay"));
		wrapper.lambda().ge(ObjectUtil.isNotEmpty(params.get("createTimeBegin")), OrderSettle::getCreateTime, params.get("createTimeBegin"));
		wrapper.lambda().le(ObjectUtil.isNotEmpty(params.get("createTimeEnd")), OrderSettle::getCreateTime, params.get("createTimeEnd"));
		wrapper.lambda().ge(ObjectUtil.isNotEmpty(params.get("settleTimeBegin")), OrderSettle::getSettleTime, params.get("settleTimeBegin"));
		wrapper.lambda().le(ObjectUtil.isNotEmpty(params.get("settleTimeEnd")), OrderSettle::getSettleTime, params.get("settleTimeEnd"));
		wrapper.lambda().orderByDesc(OrderSettle::getId);
		return wrapper;
	}

	/**
	 * 支付单号查询
	 */
	public List<OrderSettle> getByPayNo(String payNo) {
		return baseMapper.selectList(Wrappers.<OrderSettle>lambdaQuery().eq(OrderSettle::getPayNo, payNo));
	}

	/**
	 * 订单号查询
	 */
	public OrderSettle getByOrderNo(String orderNo) {
		return baseMapper.selectOne(Wrappers.<OrderSettle>lambdaQuery().eq(OrderSettle::getOrderNo, orderNo));
	}

	/**
	 * 订单号删除
	 */
	public void removeByOrderNo(String orderNo) {
		baseMapper.delete(Wrappers.<OrderSettle>lambdaQuery().eq(OrderSettle::getOrderNo, orderNo));
	}

	/**
	 * 统计
	 */
	public Double sumFields(Map<String, Object> params, String fields) {
		QueryWrapper<OrderSettle> wrapper = Wrappers.query();
		wrapper.select(StringUtil.format("ifnull(sum({}),0) as total", fields));
		wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("sellerId")), OrderSettle::getSellerId, params.get("sellerId"));
		wrapper.lambda().eq(ObjectUtil.isNotEmpty(params.get("payStatus")), OrderSettle::getPayStatus, params.get("payStatus"));
		wrapper.lambda().ge(ObjectUtil.isNotEmpty(params.get("beginTime")), OrderSettle::getCreateTime, params.get("beginTime"));
		wrapper.lambda().le(ObjectUtil.isNotEmpty(params.get("endTime")), OrderSettle::getCreateTime, params.get("endTime"));
		return Double.valueOf(getMap(wrapper).get("total").toString());
	}

	/**
	 * 支付成功处理
	 */
	public int updateByPaySuccess(String payNo, String bizPayNo, String payType) {
		return baseMapper.updateByPaySuccess(payNo, bizPayNo, payType);
	}


	/**
	 * 订单结算
	 */
	@Transactional(rollbackFor = Exception.class)
	public boolean settleOrder(Serializable id) {
		Date date = new Date();
		OrderSettle orderSettle = baseMapper.selectById(id);

		if(OrderSettleWayEnum.ONE.getCategory() == orderSettle.getSettleWay()){
			if(orderSettle.getSettleAmount() > 0){
				sellerService.updateSellerMoney(WalletDTO.builder()
					.userId(orderSettle.getSellerId())
					.amount(orderSettle.getSettleAmount())
					.type(WalletTypeEnum.ADD.getType())
					.sourceId(orderSettle.getOrderNo())
					.sourceType(WalletSourceEnum.ORDER_SETTLE.getType())
					.remark(WalletSourceEnum.ORDER_SETTLE.getName())
					.build());
			}
			updateById(OrderSettle.builder().id(orderSettle.getId()).settleStatus(1).settleRemark("结算成功").settleTime(date).build());
			return true;
		}

		if(OrderSettleWayEnum.TOW.getCategory() == orderSettle.getSettleWay()){
			IPayGranter iPayGranter = PayGranterBuilder.getGranter(orderSettle.getPayType());
			//添加分帐方账户
			SettleUserVO settleUserVO = iPayGranter.settleUser(SettleUserDTO.builder().type(1).relationType("STORE").targetId(orderSettle.getSellerId()).build());
			if(!Objects.equals(StringPool.YES, settleUserVO.getCode())){
				updateById(OrderSettle.builder().id(orderSettle.getId()).settleStatus(-1).settleRemark("添加分账方失败：" + settleUserVO.getMsg()).settleTime(date).build());
				return false;
			}
			//进行分账
			SettleOrderVO settleOrderVO = iPayGranter.settleOrder(SettleOrderDTO.builder().settleNo(orderSettle.getId().toString()).payBizNo(orderSettle.getPayBizNo()).type(1).targetId(orderSettle.getSellerId()).amount(orderSettle.getSettleAmount()).build());
			if(!Objects.equals(StringPool.YES, settleOrderVO.getCode())){
				updateById(OrderSettle.builder().id(orderSettle.getId()).settleStatus(-1).settleRemark("分账失败：" + settleOrderVO.getMsg()).settleTime(date).build());
				return false;
			}else{
				updateById(OrderSettle.builder().id(orderSettle.getId()).settleStatus(1).settleRemark("结算成功，结算单号：" + settleOrderVO.getMsg()).settleTime(date).build());
				return true;
			}
		}
		return false;
	}
}
